home *** CD-ROM | disk | FTP | other *** search
/ MacHack 1994 / MacHack 1994.toast / MacHack™94 / Talks & Papers / Timothy Knox / yerk 3.66 / System source / Class < prev    next >
Text File  |  1994-06-24  |  18KB  |  601 lines

  1. \ Class/Object general properties and compilation code
  2. \  4/26/84  CBD Version 1.0
  3. \  4/26/84  CBD Speeded up ^Elem and friends
  4. \  4/27/84  CBD Moved rect, etc. to QD  file
  5. \  5/02/84  CBD Removed IX-non-IX restriction
  6. \  5/24/84  NDI Remove selector numbering, add objlen
  7. \  5/26/84  CBD Took non-class stuff out
  8. \  5/28/84  CBD Selectors defer refs to input parm objects
  9. \ 10/04/84  CBD Added class initialization, text messages
  10. \ 10/11/84  CBD objPtr and objArray support
  11. \ 10/12/84  CBD Added GET: and PUT: for arrays
  12. \ 10/18/84  CBD converted to mcfa Values
  13. \ 10/30/84  CBD propagate classInit: thru Ivar chains at create
  14. \ 11/02/84  CBD objects have executable CFA
  15. \ 11/02/84  CBD update for optimized array support in nucleus
  16. \ 11/16/84  CBD removed objArray, etc.
  17. \ 12/08/84  CBD ß1.0 version
  18. \ 12/14/84  cbd removed read:, write:, etc
  19. \ 12/15/84  cbd hashed selectors
  20. \ 12/12/85  cdn Put CR after redefined message in :M
  21. \  8/01/86  cdn Added "Method redefined, within same class ****" message
  22. \ 12/27/89    rfl    changed ?isclass to check for valid ram for @
  23. \  1/11/90    rfl    need to change traverse or at least ?cfa in nuc to protect for valid ram
  24. \ 11/23/90    rfl    Method redefined message now comes before selector for readability
  25. \ 12/17/90    rfl    added class name to above
  26. \  6/01/91    rfl    ovblock modified for sys 7...heap is below 0;
  27. \ 12/12/92    rfl 32 bit hash for methods; move ?rdepth to this source
  28. \ 12/25/92    rfl    changed nuc to set heapBot, heapTop in relative addr space
  29. \ 12/26/92    rfl object name not unique error gives name of object
  30. \  5/28/93    rfl    added within and used it in (@)
  31. \  6/04/93    rfl    modified (build) for source documentation (line#..)
  32. \  3/03/94    rfl ;class now handles smudge so classes can be redefined with same name
  33.  
  34. 0 value (rdepth)
  35. : +rdepth 1 -> (rdepth) ;
  36. : -rdepth 0 -> (rdepth) ;
  37. : ?Rdepth (rdepth) IF  rdepth  220 > ?error 116 THEN ;
  38.  
  39. : +docs true -> docs ;
  40. : -docs false -> docs ;
  41.  
  42. : ^CLASS   current  @ pfa ;
  43.  
  44. \ the following offsets refer to the ^class, or Pfa of the class.
  45. : MFA    10 + ;    \ methods dictionary Latest field
  46. : IFA    14 + ;    \ ivar dict Latest field
  47. : DFA    18 + ;    \ Datalen , width of indexed area
  48. : SFA    22 + ;    \ superclass ptr field
  49.  
  50. \ Get length of object's named ivars
  51. : @DLEN cfa @ Dfa  W@   ;
  52.  
  53. \ ( SelPfa ^class -- m1cfa )  Find a method in a class
  54. : (FINDM)
  55.     swap over mfa ((findm))  0=
  56.     IF  cr msg# 108  nfa .name
  57.         abort
  58.     ELSE  swap drop THEN ;
  59.  
  60. \ ( Selhash objPfa -- objPfa m1cfa )
  61. \  Find a method 1cfa given a selector ID
  62. : FIND-METHOD
  63.     dup 0= ?error 103
  64.     swap over CFA @ (FINDM)  ;
  65.  
  66. \ ( objAddr -- )  Look up SelID at IP and run the method
  67. : (Defer)
  68.     w@(ip)    \ objPfa  selID
  69.     Swap  Find-Method Cfa    \ objAddr m0cfa
  70.     execute  ;    \ exec the  m0cfa
  71.  
  72.    0 Value  ^Self
  73.    0 Value  ^Super        \ nfa of SUPER pseudo-Ivar
  74.    0 Value  newObject    \ object being created
  75.    1 Value  rangeCheck    \ true if runtime range check desired
  76. true Value dEcho        \ echo load to screen?
  77.  
  78. 0 -> quitvec    \ clear vectors
  79. 0 -> abortvec
  80. 0 -> objInit
  81. 'c pfind -> ufind
  82.  
  83. \ ( addr -- hashVal )  hash a  name into a 16-bit word
  84. : Hash { addr -- }
  85.     0 addr count +  addr
  86.     DO 4* Dup 65535 > IF 1+ THEN
  87.         I  C@ 32 - xor  65535 And
  88.     LOOP ;
  89.  
  90. : within { n lo hi -- b } n lo >= n hi <= and ;
  91.  
  92. \ check to make sure the memory addressed is within the application heap zone
  93. : (@) ( addr -- n t or f)  dup heapBot heapTop within
  94.     IF @ true ELSE drop false THEN ;
  95.  
  96. \ ( pfa -- pfa b )  returns true if a class -  make sure pfa points within appl
  97. : ?IsClass  'CODE DoClass OVER CFA (@) IF = ELSE drop false THEN ;
  98.  
  99. \ ( pfa -- pfa b )  return true if an object
  100. :f ?IsObj
  101.     ?IsClass
  102.     IF  False
  103.     ELSE Dup cfa (@)
  104.         IF ?IsClass swap drop ELSE false THEN 
  105.     THEN ;f
  106.  
  107. \ ( pfa -- pfa b )  return true if an object vector
  108. : ?IsVect  dup cfa (@) IF  valCode = over cfa @ vectCode = or ELSE false THEN ;
  109.  
  110. \ ( pfa -- pfa b )  is ref'd word an open bracket?
  111. : ?IsParen  dup nfa 1+ c@ ascii [ =  ;
  112.  
  113. \ ( -- )  ERROR if not compiling a new class definition
  114. : ?Class   Cstate   0=  ?error 115  ;
  115.  
  116. \ ( classIFA -- f OR 1cfa t )  search CLASS dictionaries
  117. : ivarFind   here hash swap ((findm))   ;
  118.  
  119. \ ( -- f OR pfa t )  Determine if  next word is an instance var
  120. : vFind
  121.     bl word  Cstate
  122.     IF    \ class compile?
  123.         ^class  IFA ivarFind    \ search IVAR chain
  124.     ELSE  0 THEN ;    \ leave ff
  125.  
  126. \ Key to instantiation actions
  127. \ notFnd    -not previously defined
  128. \ objTyp    -defined as an object
  129. \ classTyp    -as a class
  130. \ vecTyp    -as an object vector- ptr, array, etc
  131. \ parmTyp    -as a named parm
  132. \ parenType    -open paren for defer group
  133.  
  134. \ ( #elems ^class  OR ^class -- indlen )
  135. : IDX-HDR   DFA 2+ W@ DUP IF  2DUP W, W,  * align THEN ;
  136.  
  137. \ ( IVnfa -- ivlfa )
  138. : ilfa   2+ ;
  139.  
  140. \ ( ilfa -- icfa )
  141. : ^ICLASS  CFALEN + @ ;
  142.  
  143. \ ( ^class -- elWidth )  return the indexed element width for class
  144. : @width   dfa 2+ w@  ;
  145.  
  146. \ ( infa -- icfa )  transform ivar nfa to its class field
  147. : icfa  ilfa  4+  ;
  148.  
  149. \ ( ivarlfa -- #els  wid  idxOffs  tf OR ff )
  150.  
  151. \ ( ivarNfa -- IvarNfa b )  True if nfa is Super or Self
  152. : ?LastIvar         Dup  ^Self   = Over ^Super   = OR ;
  153.  
  154. \ InitIvar  performs the classInit: method on the ivar on the stack )
  155. Forward InitIvar
  156.  
  157. \ ( ivarNfa -- latestNfa )  -> Latest nested Ivar
  158. : ^LatestIvar    ilfa ^Iclass  IFA  @  ;
  159. : ^NextIvar      ILFA  @ ;
  160.  
  161. \ ( ivarnfa -- ivoffs )  Return ivar's offset
  162. : @IvarOffs  ILFA  8+ W@  ;
  163.  
  164. \ ( ivarNfa -- IvarNfa newNfa t  OR  ivarNfa f )
  165. : ?Nest
  166.     Dup ^LatestIvar  ?LastIvar
  167.     IF  Drop 0 ELSE 1 THEN ;
  168.  
  169. \ ITRAV traverses the tree of nested ivar definitions in a
  170. \ class, building necessary indexed area headers
  171. \ the Mstack has the base offset for nested Ivars
  172. \ ( ivarNfa -- )
  173. : ITRAV
  174.     BEGIN  ?Rdepth ?Nest
  175.         IF Over @IvarOffs Dupm Addm Itrav THEN
  176.         Dup
  177.         ILFA dup    \ DO-NODE - Build header if indexed ivar
  178.         pushm copym ^iclass -dup    \ HDR-INFO
  179.         IF  copym $ 0a + w@  popm 8+ w@   ( #els  offs )
  180.             rot dup dfa w@ rot + swap @width  ( #els truoffs wdth)
  181.             swap over -dup
  182.             IF ELSE 2drop drop 0 THEN
  183.         ELSE  dropm 0 THEN    \ not idx
  184.         IF  CopyM +    \ add in nested base offset
  185.             pushm copym newObject  + w!   ( ! el-width )
  186.             popm  newObject  +  2+ W!  ( !  # els )
  187.             dup 4+ @        \ get ^class of indexed Ivar
  188.             over 8+ w@        \ get offs this ivar
  189.             copym  newObject + + cfa !    \ store in cfa
  190.         THEN  initIvar
  191.         ^NextIvar  ?LastIvar  Not
  192.     WHILE  REPEAT
  193.     DROP DropM ;
  194.  
  195. Forward  ClassInit
  196.  
  197. \ ( #elems ^class OR ^class -- ) Compile an instance variable dictionary entry
  198. : <VAR
  199.     pushm    \ place ^class on methods stack for later
  200.     Vfind  ?error 117
  201.     here dup hash w,        \ compile hashed ivar name into dict
  202.     ^Class IFA dup @ ,  !  COPYM  ,  ( link, class )
  203.     copym @width
  204.     IF  4 ^class dfa w+! THEN    \ if indexed, save 4 for cfa
  205.     ^Class DFA  W@  W,            \  ( current dLen= offset )
  206.     copym @width dup
  207.     IF over * swap W, 4+ THEN  ( #elems)
  208.     popM DFA W@  +  align    \ Account for named ivar lengths
  209.     ^Class  DFA   W+!   ;
  210.  
  211. \ ( -- )  Create hdr for the name at Here
  212. : CreateHdr
  213.     Here 1+ c@ 0= ?error 118
  214.     $ 80 S, latest , current !  0,   ;
  215.  
  216. \ ( m1cfa n -- )  Execute the ncfa of word on stack
  217. \ takes a standard Pfa = 1cfa as input
  218. \ : mExec  clen * swap 4- + Execute ;
  219.  
  220. \ ( #elems ^class OR ^class -- )  Build an instance of a class
  221. : (BUILD)
  222.     Pushm  Cstate
  223.     IF  Popm  <Var    \ build an ivar
  224.     ELSE
  225.         \ NEWTOKEN : pulls name from stream
  226.         Here 1 and IF 0 c, THEN docs IF line# w, THEN Find
  227.         IF drop ?isVect
  228.             IF  3 ( vecTyp )
  229.             ELSE  1 ( objTyp )
  230.             THEN
  231.         ELSE 0 ( notFnd ) THEN    ( -- pfa type OR 0 )
  232.  
  233.         \ OBJHDR :
  234.         \ Build a public  object header or just a cfa if headerless
  235.         \ If an object vector, load pfa of object into vector
  236.         \ ( {vectPfa} objType -- )  HERE is left at pfa of new object
  237.         Select{    \ on object type
  238.             0 ( notFnd )    Is{  CreateHdr  }End    \ not redefined
  239.  
  240.             1 ( objTyp )    Is{  drop createHdr
  241.                 type# 181 ( Object name not unique ) latest id.  cr   }End
  242.  
  243.             2 ( classtyp )  Is{ abort }End        \ should not get this
  244.  
  245.             \ ( ind vecPfa -- )  for object vectors, execute -> code at 2cfa
  246.             3 ( vecTyp )   Is{  0, Here  swap 2 clen * swap 4- + Execute
  247.                 msg# 120  }End
  248.  
  249.         Default{ abort }Select
  250.  
  251.         Here  -> newObject
  252.         Copym here  cLen - !    \ store ^class
  253.         copym  DFA  W@            ( dfa datalen )
  254.         Reserve        \ allocate named instances
  255.         copym  IDX-HDR  reserve
  256.         popm IFA @  ?LastIVar not
  257.         IF  0 Pushm Itrav ELSE drop THEN
  258.         classInit
  259.     THEN  ;
  260.  
  261. \ yerk grow zone function
  262. 'c null vect growZone
  263.  
  264. \ ( size -- addr )  acquire a block of nonrelocatable heap
  265. : ovBlock { size -- addr }
  266.     size  newPtr  dup +base 0=
  267.     IF  drop growZone  size newPtr dup +base 0=
  268.         ?error 121
  269.     THEN ;
  270.  
  271. \ build a new object on the heap for class. Use: Heap> className
  272. \ gets heap, and returns  relative  ptr
  273. : (heapObj) { theClass \ dLen obAddr idWid #els -- } 0 -> #els
  274.     theClass dfa w@ -> dlen  theClass dfa 2+ w@ -> idWid
  275.     idWid  IF -> #els THEN
  276.     dLen 4+ idWid IF  idWid #els * 4+ + THEN    \ get total length of obj
  277.     ovBlock  4+ -> obAddr    \ get nonReloc heap, save ptr to cfa
  278.     theClass obAddr cfa !    \ create the class ptr
  279.     idWid  IF  idWid  obAddr dLen + w!  #els obAddr dLen + 2+ w! THEN
  280.     obAddr -> newObject  theClass ifa @  ?LastIvar not
  281.     IF 0 PushM Itrav ELSE Drop THEN classinit obAddr   ;
  282.  
  283. : heap>
  284.     @pfa ?isClass not ?error 122
  285.     state
  286.     IF  Compile lit  ,
  287.         Compile (heapObj) ELSE (heapObj)
  288.     THEN
  289. ; Immediate
  290.  
  291. \ ( -- )  Set CSTATE to compiling a class
  292. : ]C  1 -> Cstate ; Immediate
  293. : C[  0 -> Cstate ; Immediate
  294.  
  295. \ compile hashed word for name at Here
  296. : hash,  @word hash w,  ;
  297.  
  298. $ 81FE0000 variable  aName  0 W,    \ fake name/link
  299.  
  300. \ ( -- )  The super class of Object - top of all inheritance
  301. : Meta
  302.     <[  'Code doClass ^Class CFA !
  303.     here 10 allot  'code objmp swap 10 cmove    \ jump to object code
  304.     aName ,        \ latest method pointer
  305.     0,            \ latest ivar pointer -> SUPER
  306.     0,   ( data len, flags)
  307.     0,   ( super pointer)  HERE -> ^SELF
  308.     hash, SELF    \ SELF ivar
  309.     0, 0, 65535 W,     ( link, ^class, offset)
  310.     Here  -> ^Super    \ save this address for later
  311.     hash, SUPER
  312.     ^self , 0, 65535 W,   ( link, ^class, offset )
  313.  
  314. ^super ' meta ifa !
  315.  
  316. \ ( -- )  Build a class header with its superclass pointer
  317. : <Super
  318.     @pfa dup        \ find the superclass
  319.     dup  ^Super icfa !    \ store superclass in SUPER
  320.     CFA here CFA    \ Set up for cmove to sub class
  321.     26 Cmove        \ create image of superclass header
  322.     ^Class SFA !    \ store superclass pointer
  323.     ^Class  ^Self icfa !    \ store ^class in SELF's icfa
  324.     26 allot
  325.     [Compile]  ]C [Compile]   <[    \ in class, interpret
  326. ; Immediate
  327.  
  328. 'c copym Vect caller    \ late bound reference to calling object
  329.  
  330. \ ( -- b )  true if word at Here is a selector xxx:
  331. : ?isSel  here count 1- + c@ ascii :  =  here c@ 1 > And ;
  332.  
  333. \ get a selector from the input stream
  334. : getSelect
  335.     @word dup c@ 15 >
  336.     ?error 123
  337.     ?isSel 0= ?error 124
  338.     hash  ;
  339.  
  340. \ ( -- )  Build a methods dictionary entry for selector
  341. : :M { \ selID -- }
  342.     ?Class  !Csp  [Compile] ]>
  343.     getSelect -> selID
  344.     selID ^class mfa ((findm))    \ is method already defined?
  345.     IF  type# 182 here count type  ( Method redefined )
  346.         space latest id.            \ add class name
  347.         ^class > IF type# 183 ( , within same class **** ) THEN cr
  348.     THEN
  349.     here  selID w,        \ name is selector's hashed value
  350.     ^class mfa dup @    \ get  mfa, old link
  351.     ,  !    \ establish the links
  352.     \ build methods cfas
  353.     'Code  M0CFA ,  'Code M1CFA ,
  354. ; Immediate
  355.  
  356. \ ( -- pfa tokenID )  Determine type of token referenced by selector.
  357. : refToken
  358.     uFind    \ look for named stack parm
  359.     IF  drop  4 ( parmTyp )
  360.     ELSE  here latest (find)  0=
  361.         ?error 125  drop  ?IsClass
  362.         IF  2 ( classTyp )
  363.         ELSE  ?IsVect
  364.             IF  3 ( vecTyp )
  365.             ELSE  ?IsObj
  366.                 IF  1 ( objTyp )
  367.                 ELSE  ?IsParen
  368.                     IF  5 ( parenType )
  369.                     ELSE  1 ?error 126
  370.                     THEN
  371.                 THEN
  372.             THEN
  373.         THEN
  374.     THEN  ;
  375.  
  376. \ ( objpfa -- a:datalen )
  377. : ^dlen   cfa @ dfa ;
  378.  
  379. \ ( ivarPfa  m1cfa )  compile an Ivar reference
  380. : ivar,    ,   w@ w,   ;    \ | 1cfa | offs |
  381.  
  382. \ ( objPfa  m0cfa )  compile an object ref
  383. : obj,   swap cfa , ,  ;    \ | objCfa | m0cfa |
  384.  
  385. \ ( selID ivPFa )
  386. : ivarRef    Find-Method ivar,   ;
  387.  
  388. \ ( selID -- )  Build a reference to an object or vector
  389. : objRef  refToken
  390.     SELECT{
  391.         0 ( notFnd )    IS{   abort  }END
  392.  
  393.         ( selID objPfa -- )
  394.         1 ( objTyp )    IS{ cfa execute
  395.             Find-Method cfa obj,   }END    \ normal obj ref
  396.  
  397.         2 ( classTyp )  IS{   (FINDM) cfa ,  }END    \ compile m0cfa
  398.  
  399.         ( selPfa  vecPfa -- )
  400.         3 ( vecTyp )    IS{  cfa , Compile (defer) w,  }END
  401.  
  402.         4 ( parmTyp )   IS{  cfa  ,    \ named parm- compile the pickCfa
  403.             Compile (Defer) W, }END    \ auto deferred
  404.  
  405.         5 ( parenType ) IS{  drop pushM  251   }END    \ paren'd defer group
  406.  
  407.     DEFAULT{  abort
  408.     }SELECT  ;
  409.  
  410. \ ( selPfa -- )  Execute using token in stream
  411. : runRef
  412.     @Pfa  drop  refToken
  413.     Select{
  414.         0 ( notFnd )     Is{  abort   }End
  415.         1 ( objTyp )     Is{  cfa execute  Find-Method    }End
  416.         2 ( classTyp )   Is{  (Findm)    }End
  417.  
  418.         ( selID  vecPfa -- )
  419.         3 ( vecTyp )     Is{  cfa execute  Find-Method    }End
  420.  
  421.         4 ( parmTyp )    Is{ abort    }End
  422.  
  423.         \ open bracket denotes a deferred ref to what
  424.         \ the paren'd group puts on the stack at runtime
  425.         5 ( parenType )  Is{  drop  Pushm ' null  }End
  426.  
  427.     Default{ abort
  428.     }Select  cfa  execute ;    \ execute the object, m0cfa
  429.  
  430. \ ================= Selector support ==========================
  431. \ message is the message compiler invoked by using a selector
  432. : message
  433.     state
  434.     IF    \ Compile state
  435.         VFIND    \ instance variable?
  436.         IF   ivarRef    \ ivar reference
  437.         ELSE   objRef    \ compile object/vector reference
  438.         THEN
  439.     ELSE runRef    \ run state - execute object/vector ref
  440.     THEN
  441. ; Immediate
  442.  
  443. \ if parsed word is a message selector, leave cfa of message compiler
  444. \ ( -- selID msgPfa 0 t OR f )
  445. : msgFind
  446.     ?isSel
  447.     IF  Here hash    \ leave selID
  448.         ' message $ c1 true
  449.     ELSE  pfind        \ look for named parms
  450.     THEN   ;
  451.  
  452. 'c msgFind -> Ufind
  453.  
  454. \ Force late binding of method to object, as in SmallTalk
  455. \ a close bracket pops the last selID from the methods stack and
  456. \ compiles a defer: selID.  This will build a deferred reference to the
  457. \ parenthesized group.
  458. : ]    State
  459.     IF  251 ?Pairs  Compile (Defer)
  460.         mdepth 0= ?error 127
  461.         popM   W,    \ Compile | {defer} |SelPfa|
  462.     ELSE  popM  Swap   Find-Method Cfa    \ exec state
  463.         execute
  464.     THEN
  465. ; Immediate
  466.  
  467. \ left bracket has no meaning unless preceded by a selector.
  468. : [  true ?error 128  ; Immediate
  469.  
  470. : ;M   ?Csp  Compile  (;M)   ;  Immediate
  471.  
  472. \ Leave class compilation state, and zero the class ptrs of Self and Super
  473. : ;Class  [Compile] <[  [Compile] C[
  474.         0  ^Super icfa !   0 ^Self icfa ! latest c@ $ df and latest c! ;  Immediate
  475.  
  476. : :Class    [Compile] :    ; Immediate
  477.  
  478. \ ( width -- )  Set a class and its subclasses to indexed
  479. : <Indexed  ?class ^class DFA 2+ W! ;
  480.  
  481. \ ( dim -- )  Set an indexed class to a multi-dimensionality
  482. \ : <Dim
  483. \    ?class ^class DFA 2+ W@ 0= ?error 175    \ misuse of <Dim
  484. \    ^class DFA 2+ c! ;
  485.  
  486. \ ( index -- addr ) ( dlen ^base -M- dlen ^base )  range check
  487. : ?Range    dup 0< >R range? R> or ClassErr" 129  ;
  488.  
  489. \ ( index -- addr )  Return pointer to indexed  element #
  490. : ^Elem
  491.     ?Class    RangeCheck
  492.     IF Compile ?range  THEN
  493.     Compile (^elem)   ;  Immediate
  494.  
  495. \ An object's base addr is always on top of mstack
  496. Create ^base    \ make code word alias
  497.     'Code copym here cfa !
  498.  
  499. \ length does not include cfa
  500. \ ( -- objlen )  compute total length of object
  501. \ - requires obj addr on mstack
  502. : objlen
  503.     copym @dlen copym ^dlen 2+ w@ -dup
  504.     IF idxBase 2- w@ * + 4+ THEN ;
  505.  
  506. \ Define  class init routine
  507. :F classInit    classinit: newObject   ;F
  508.  
  509. \ ( ^ivarLfa -- ) ( ivarOffs -M- )
  510. getSelect classInit: Constant initID
  511. :F initIvar
  512.     initID swap 8+    \ ( selID ivPfa )
  513.     dup cfa @        \ non-0 ^class?
  514.     IF  Find-Method cfa swap W@    ( 0cfa ivOffs )
  515.         copym newObject + +        ( 0cfa ^data )
  516.         swap execute            \ execute the 0cfa
  517.     ELSE  2drop        \ don't try to init Self or Super
  518.     THEN   ;F
  519.  
  520. \ clean up class compiler data on an Abort
  521. ' ;class cfa -> abortVec
  522.  
  523. \ dump will be in the Util module
  524. Forward dmp
  525.  
  526. \ install object builder
  527. ' (build) cfa -> bldvec
  528.  
  529. \ ( -- )  error if object is not indexed
  530. : ?ixObj
  531.     copym  4- @  ?IsClass not swap
  532.     dfa 2+ w@ 0= or classErr" 130 ;
  533.  
  534. : ?ixRange   ?IxObj  ?range  ;
  535. 'c ?ixRange vect ?idx
  536.  
  537. : +range  'c ?ixRange -> ?idx  ;
  538. : -range  'c null -> ?idx ;    \ no range checking
  539.  
  540. :CLASS Object  <Super Meta
  541.  
  542.     :M  AT:    ?idx  At4    ;M   ( index -- val )
  543.     :M  TO:    ?Idx  (^elem) !    ;M   ( val Index -- )
  544.     :M  +TO:   ?idx  ++4   ;M   ( incVal index -- )
  545.     :M  ^ELEM: ?Idx   ^elem        ;M   ( index -- addr )
  546.  
  547.     \ Leave max #elements for array
  548.     :M  LIMIT: ?ixObj limit  ;M    ( -- limit )
  549.  
  550.     \ ( e0 e1... en -- )  indexed PUT: loads array from stack
  551.     :M  PUT:   ?ixObj limit 0
  552.         DO   limit i- 1- (^elem) !  LOOP   ;M
  553.     \ ( -- e0 e1 ...en)  Indexed GET: places elements on stack
  554.     :M  GET:   ?ixObj limit 0 DO i at4  LOOP ;M
  555.  
  556.     :M  CLASS: copym  cfa  @  ;M    \  non-IX - leave class ptr
  557.  
  558.     \ ( -- addr len )  leave class name string for object
  559.     :M  WIDTH: ?ixObj  idxBase  4-  W@  ;M    \ IX - element size for array
  560.  
  561.     \ ( value -- )  Fill all elements with a value
  562.     :M  FILL:  limit 0 DO  dup i to: self     LOOP drop   ;M
  563.  
  564.     \ ( -- )  Indexed Clear: erases indexed area
  565.     :M  CLEAR:  idxBase  Width: self Limit: Self * Erase ;M
  566.  
  567.     :M  ABS:       (abs)   ;M    \  Absolute copy of mstack
  568.     :M  ADDR:      copym   ;M
  569.  
  570.     \ ( -- addr )  Leave addr of 0th indexed element
  571.     :M  IXADDR:    idxBase   ;M
  572.  
  573.     \ ( -- len )  Return total length of object
  574.     :M  LENGTH:    objlen      ;M
  575.     :M  PRINT:     copym objlen dmp ;M
  576.     :M  DUMP:      print: self  ;M    \ alias for Print:
  577.     :M  CLASSINIT:    ;M    \ null method for object init
  578.  
  579. ;CLASS
  580.  
  581. \ Bytes is used as the allocation primitive for basic classes
  582. : BYTES  ?Class  ' Object <Var  ^Class Dfa W+!  ;
  583.  
  584. \ define code words to get and set handle sizes
  585. \ ( handle size -- RC )  set handle size with condition code
  586. Create setHSize
  587.     popD0
  588.     popA0
  589.     $ a024 w,    \ call SetHandleSize
  590.     pushD0
  591.     next,
  592.  
  593. \ ( handle -- size )  get handle size
  594. Create getHSize
  595.     popA0
  596.     $ a025 w,    \ call GetHandleSize
  597.     pushD0
  598.     next,
  599.  
  600. <" Struct
  601.